/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package rbb.itm5.bwinf.roboter.Control.Drivers;

import java.awt.Point;
import java.awt.Rectangle;
import rbb.itm5.bwinf.roboter.Control.DriverInterface;
import rbb.itm5.bwinf.roboter.Control.Roboter;
import rbb.itm5.bwinf.roboter.Model.Obstacle;

/**
 *
 * @author Anton Töws
 */
public class Toews extends DriverInterface {

    private Rectangle room = new Rectangle(0, 0, 1, 1);
    private int strateOn = 0, counter = 0, weg = 4;
    private int MinimumX = 0, MaximumX = 0, MinimumY = 0, MaximumY = 0;
    private boolean forward = false, left = false, right = false;

    public Toews(Roboter robot) {
        super(robot);
        paintObstacles = true;
    }

    @Override
    protected void drive() throws InterruptedException {
        while (!isPaused() && !robot.checkGoalHasFound()) {
            boolean oldLeft = left, oldRight = right;
            forward = robot.goForward();
            left = robot.hasLeftColision();
            right = robot.hasRightColision();

            if (!forward) {
                registerObstacle(robot.getDirection());
            }
            if (left) {
                registerObstacle(robot.getDirectionLeft());
            }
            if (right) {
                registerObstacle(robot.getDirectionRight());
            }

            if (robot.getStepCount() > 50 && oldRight && !right) {
                System.out.println("Fehler");
            }
            if (oldLeft && !left && Math.random() > 0.2) {
                robot.turnLeft();
            } else if (oldRight && !right && Math.random() > 0.2) {
                robot.turnRight();
            } else if (forward) {
                strateOn++;
            } else {
                turn();
            }




            //Prüfe und rechne neue Raumgröße
            Point p = robot.getPostion();
            boolean MinMaxChanged = false;
            if (p.x < MinimumX) {
                MinimumX = p.x;
                MinMaxChanged = true;
            }
            if (p.x > MaximumX) {
                MaximumX = p.x;
                MinMaxChanged = true;
            }
            if (p.y < MinimumY) {
                MinimumY = p.y;
                MinMaxChanged = true;
            }
            if (p.y > MaximumY) {
                MaximumY = p.y;
                MinMaxChanged = true;
            }
            if (MinMaxChanged) {
                Rectangle oldRoom = new Rectangle(room);
                room.setLocation(MinimumX, MinimumY);
                room.setSize(Math.abs(MinimumX) + MaximumX + 1, Math.abs(MinimumY) + MaximumY + 1);
                RoomSizeChanged(oldRoom);
            }
            waitForNextStep();
        }
    }

    private void registerObstacle(int direction) {
        Point p = robot.getPostion();
        switch (direction) {
            case Roboter.DIRECTION_UP:
                p.y--;
                break;
            case Roboter.DIRECTION_LEFT:
                p.x--;
                break;
            case Roboter.DIRECTION_DOWN:
                p.y++;
                break;
            case Roboter.DIRECTION_RIGHT:
                p.x++;
                break;
        }
        Obstacle ob = findObstacle(p.x, p.y);
        if (ob == null) {
            //System.out.println("Hinderniss "+Roboter.DIRECTION[direction]+" auf ("+p.x+","+p.y+")");
            boolean onWall = false;
            if (p.x == room.x - 1 || p.x == room.width - room.x || (room.x < 0 && p.x == room.width + room.x)) {
                onWall = true;
            }
            if (p.y == room.y - 1 || p.y == room.height - room.y || (room.y < 0 && p.y == room.height + room.y)) {
                onWall = true;
            }
            if (onWall) {
                obstacles.add(new Obstacle(p.x, p.y, 1, 1, true));
            } else {
                obstacles.add(new Obstacle(p.x, p.y, 1, 1));
            }
        }
    }

    private Obstacle findObstacle(int direction, Point p) {
        switch (direction) {
            case Roboter.DIRECTION_UP:
                p.y--;
                break;
            case Roboter.DIRECTION_LEFT:
                p.x--;
                break;
            case Roboter.DIRECTION_DOWN:
                p.y++;
                break;
            case Roboter.DIRECTION_RIGHT:
                p.x++;
                break;
        }
        return findObstacle(p.x, p.y);
    }

    private Obstacle findObstacle(int x, int y) {
        Obstacle re = null;
        margeObstacles();
        for (Obstacle ob : obstacles) {
            if (ob.getPostion().x == x && ob.getPostion().y == y) {
                re = ob;
                break;
            }
            if (x > ob.getPostion().x && x > ob.getPostion().y && x <= ob.getPostion().x + ob.getSize().width - 1 && y <= ob.getPostion().y + ob.getSize().height - 1) {
                re = ob;
                break;
            }
        }
        return re;
    }

    private void margeObstacles() {
    }

    private void RoomSizeChanged(Rectangle oldRoom) {
        //System.out.println("x="+room.x+"  y="+room.y+"  w="+room.width+"  h="+room.width);
        //Alte Wände enfternen
        int remove = 0;
        boolean onWall = true;
        for (Obstacle ob : obstacles) {
            onWall = false;
            if (counter == 4 && strateOn == 1 && ob.getPostion().y == 1) {
                System.out.println("Fehler");
            }
            if (ob.getPostion().x == room.x - 1 || ob.getPostion().x + ob.getSize().width - 1 == room.width - room.x || (room.x < 0 && ob.getPostion().x + ob.getSize().width - 1 == room.width + room.x)) {
                onWall = true;
            }
            if (ob.getPostion().y == room.y - 1 || ob.getPostion().y + ob.getSize().height - 1 == room.height - room.y || (room.y < 0 && ob.getPostion().y + ob.getSize().height - 1 == room.height + room.y)) {
                onWall = true;
            }
            if (!onWall && ob.isOnTheWall()) {
                remove++;
            }
            ob.setEditable(true);
            ob.setOnTheWall(onWall);
        }
        if (remove > 0) {
            System.out.println(remove + " Wandhindernisse wurden entfernt");
        }
    }

    private void turn() {
        boolean left = robot.hasLeftColision(), right = robot.hasRightColision();
        if (!left && !right) {
            if (Math.random() >= 0.5) {
                robot.turnLeft();
            } else {
                robot.turnRight();
            }
        } else if (!left) {
            robot.turnLeft();
        } else if (!right) {
            robot.turnRight();
        }
        strateOn = 0;
    }

    @Override
    public String getName() {
        return "Töws";
    }

    @Override
    protected void onStart() {
        obstacles.clear();
        strateOn = 0;
        counter = 0;
        room = new Rectangle(0, 0, 1, 1);
        MinimumX = 0;
        MinimumY = 0;
        MaximumX = 0;
        MaximumY = 0;
    }
}
